

package modelo;

import proyecto2011.Archivo;
import java.util.Iterator;
import java.util.Vector;

/**
 * Clase que representa una Tabla del Esquema
 * @author Jaime Painefilu - Juan Demo 
 */
public class Tabla {
    String nombre;
    int nroAtributos;
    String pkTabla;
    Vector Index;  ////
    Vector fkTabla;
    Vector atributos;
    Vector triggers;
    Vector checks;

    public Tabla(String nombre) {
        this.nombre = nombre;
        this.nroAtributos = 0;       
        pkTabla = null;
        Index = new Vector();
        fkTabla = new Vector();
        atributos = new Vector();
        checks = new Vector();
        triggers = new Vector();
    }

    public void showTabla(Archivo arch){
        arch.escribirLinea("  "+nombre+" (");
        this.showAtributos(arch);
        arch.escribirLinea("\n    * ");
        this.showPkTabla(arch);
        this.showFks(arch);
        showChecks(arch);
        showIndexs(arch);
        showTriggers(arch);
        arch.escribirLinea("  )\n");
        
    }
                             
    
    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getNroAtributos() {
        return nroAtributos;
    }

    public void setNroAtributos(int nroAtributos) {
        this.nroAtributos = nroAtributos;
    }

    public Vector getAtributos() {
        return atributos;
    }

    public void setAtributos(Vector atributos) {
        this.atributos = atributos;
    }

    public void addAtributos(Atributo at){
        this.atributos.addElement(at);
        this.nroAtributos++;
    }

    public void showAtributos(Archivo arch){
        Atributo aux;
        for(int i=0; i<this.atributos.size(); i++){
            aux = (Atributo) this.atributos.elementAt(i);
            aux.showAtributo(arch);
        }
    }

    public int existAtributo(String nAtributo){
        Atributo atrib;
        int pos = -1;
        for(int i=0; i<this.atributos.size(); i++){
            atrib = (Atributo) this.atributos.elementAt(i);
            if(atrib.getNombre().equals(nAtributo)) pos = i;
        }
        return pos;
    }

    public void addIndex(Index ind){
        this.Index.addElement(ind);
    }

    public Vector getIndex() {
        return Index;
    }

    public void setIndex(Vector Index) {
        this.Index = Index;
    }

    public void delIndex(int pos){
        this.Index.remove(pos);
    }

    public int existIndex(String nIndex){
        Index indx;
        int pos = -1;
        for(int i=0; i<this.Index.size(); i++){
            indx = (Index) this.Index.elementAt(i);
            if(indx.getNombreIndex().equals(nIndex)) pos = i;
        }
        return pos;
    }

    public void showIndexs(Archivo arch){
        Index aux;
        System.out.println();
        for(int i=0; i<this.Index.size(); i++){
            aux = (Index) this.Index.elementAt(i);
            arch.escribirLinea("        ");
            aux.showIndex(arch);
        }
    }

    public String getPkTabla() {
        return pkTabla;
    }

    public void setPkTabla(String pkTabla) {
        this.pkTabla = pkTabla;
    }

    public void showPkTabla(Archivo arch){
        if(pkTabla.length()!= 0) arch.escribirLinea(pkTabla+"\n");
        else arch.escribirLinea(" <<**ATENCION!: NO TIENE CLAVE PRIMARIA **>>\n");
    }

    public Vector getFkTabla() {
        return fkTabla;
    }

    public int existFk(String fk){
        ForeignKey fk0;
        int pos = -1;
        for(int i=0; i<this.fkTabla.size(); i++){
            fk0 = (ForeignKey) this.fkTabla.elementAt(i);
            if(fk0.getFknombre().equals(fk)) pos = i;
        }
        return pos;
    }

    public void addFkTabla(ForeignKey fkTabla) {
        this.fkTabla.addElement(fkTabla);
    }

    public void showFks(Archivo arch){
        ForeignKey fk0;
        for(int i=0; i<fkTabla.size(); i++){
            fk0 = (ForeignKey) fkTabla.elementAt(i);
            fk0.showForeignKey(arch);
        }
    }

    public Vector getTriggers() {
        return triggers;
    }

    public void setTriggers(Vector triggers) {
        this.triggers = triggers;
    }

    public int existTriggers(String nombTrig){
        Trigger trig0;
        int pos = -1;
        for(int i=0; i<this.triggers.size(); i++){
            trig0 = (Trigger) this.triggers.elementAt(i);
            if(trig0.getNombre().equals(nombTrig)) pos = i;
        }
        return pos;
    }

    public void showTriggers(Archivo arch){
        Iterator<?> i = triggers.iterator();
        while (i.hasNext()){
        	Trigger triggerCorriente = (Trigger) i.next();
        	triggerCorriente.showTrigger(this.nombre, arch);
        }
    }

    public Vector getChecks() {
            return checks;
    }

    public void setChecks(Vector checks) {
            this.checks = checks;
    }

    public void showChecks(Archivo arch){
        for(int i=0; i<checks.size(); i++){
            arch.escribirLinea("    + "+checks.elementAt(i)+"\t\n");
        }
    }

    public int existNombreCheck(String nombCheck){
        Check ck;
        int pos = -1;
        for(int i=0; i<this.checks.size(); i++){
            ck = (Check) this.checks.elementAt(i);
            if(ck.getNombre().equals(nombCheck)) pos = i;
        }
        return pos;
    }

    public int existCondicionCheck(String condCheck){
        Check ck;
        int pos = -1;
        for(int i=0; i<this.checks.size(); i++){
            ck = (Check) this.checks.elementAt(i);
            if(ck.getCondicion().equals(condCheck)) pos = i;
        }
        return pos;
    }
    

    public void compararTabla(Tabla tabla, Archivo arch){
        Vector atributosExtras = new Vector();
        Vector fkextras = new Vector();
        Vector triggerExtras = new Vector();
        Vector checksExtras = new Vector();
        Vector indexsExtras = new Vector();
        Atributo atrib1;
        int posActual;

        /*
         * INICIA COMPARACION DE ATRIBUTOS
         */
        arch.escribirLinea("\n\n######## TABLAS EN COMUN:  '"+this.getNombre()+"' ##########\n");
        arch.escribirLinea("\n  COLUMNAS :\n");
        for(int j=0; j<tabla.getNroAtributos(); j++){
            atrib1 = (Atributo) tabla.atributos.elementAt(j);
            posActual = this.existAtributo(atrib1.getNombre());
            if(0 <= posActual){
                atrib1.compararAtributo((Atributo)this.atributos.remove(posActual), arch);
            }
            else atributosExtras.addElement(atrib1);
        }
        if(!this.atributos.isEmpty()){
            arch.escribirLinea("\n     << ADVERTENCIA! >> Atributos Extras en Tabla '"+this.getNombre()+"' (1er ESQUEMA):\n");
            arch.escribirLinea("            ");
            this.showAtributos(arch);
        }
        if(!atributosExtras.isEmpty()){
            arch.escribirLinea("\n     << ADVERTENCIA! >> Atributos Extras en Tabla '"+tabla.getNombre()+"' (2do ESQUEMA):\n");
            arch.escribirLinea("            ");
            Atributo aux;
            for(int i=0; i<atributosExtras.size(); i++){
                aux = (Atributo) atributosExtras.elementAt(i);
                aux.showAtributo(arch);
            }
            arch.escribirLinea("\n");
        }
        System.out.println();

        /*
         * INICIA COMPARACION DE CLAVES PRIMARIAS
         */
        if((!tabla.pkTabla.isEmpty()||!(this.pkTabla.isEmpty()))) arch.escribirLinea("\n  CLAVES PRIMARIAS:\n");
        if(this.pkTabla.equals(tabla.pkTabla)){
            arch.escribirLinea("     ** Claves Primarias iguales: ");
            this.showPkTabla(arch);
        }
        else{
            arch.escribirLinea("\n   << ADVERTENCIA! >> Las Claves Primaria son Distintas!!\n");
            arch.escribirLinea("\n     Clave Primaria 1er esquema: ");
            this.showPkTabla(arch);
            arch.escribirLinea("\n     Clave Primaria 2do esquema: ");
            tabla.showPkTabla(arch);
            arch.escribirLinea("\n");
        }

        /*
         * INICIA COMPARACION DE CLAVES FORANEAS
         */
        if((!tabla.fkTabla.isEmpty()||!(this.fkTabla.isEmpty()))){
            arch.escribirLinea("\n  CLAVES FORANEAS:\n");
            ForeignKey fk1;
            for(int j=0; j<tabla.fkTabla.size(); j++){
                fk1 = (ForeignKey) tabla.fkTabla.elementAt(j);
                posActual = this.existFk(fk1.getFknombre());
                if(0 <= posActual){
                    fk1.compararFk((ForeignKey)this.fkTabla.remove(posActual), arch);
                }
                else fkextras.addElement(fk1);
            }
            if(!this.fkTabla.isEmpty()){
                arch.escribirLinea("\n    << ADVERTENCIA! >> Claves Foráneas Extra en tabla '"+this.getNombre()+"' (1er ESQUEMA):\n");
                arch.escribirLinea("        ");
                this.showFks(arch);
            }
            if(!fkextras.isEmpty()){
                arch.escribirLinea("\n    << ADVERTENCIA! >> Claves Foráneas Extra en tabla '"+tabla.getNombre()+"' (2do ESQUEMA):\n");
                for(int i=0; i<fkextras.size(); i++){
                    fk1 = (ForeignKey) fkextras.elementAt(i);
                    arch.escribirLinea("        ");
                    fk1.showForeignKey(arch);
                }
                arch.escribirLinea("\n");
            }
        }

        /*
         * INICIA COMPARACION DE Indices
         */
        if((!tabla.Index.isEmpty()||!(this.Index.isEmpty()))){
            arch.escribirLinea("\n  INDICES:\n");
            Index idx;
            for(int j=0; j < tabla.Index.size(); j++){
                idx = (Index) tabla.Index.elementAt(j);
                posActual = this.existIndex(idx.getNombreIndex());
                if(0 <= posActual){
                    idx.compararIndex((Index)this.Index.remove(posActual), arch);
                }
                else{
                    int existInd = this.existIndex(idx.getNombreIndex());
                    if(0 <= existInd) idx.compararIndex((Index)this.Index.remove(existInd), arch);
                    else indexsExtras.addElement(idx);
                }
            }
            if(!this.Index.isEmpty()){
                arch.escribirLinea("     << ADVERTENCIA! >> Indexs Extras en Tabla '"+this.getNombre()+"' (1er ESQUEMA):\n");                
                this.showIndexs(arch);
                arch.escribirLinea("\n");
            }
            if(!indexsExtras.isEmpty()){
                arch.escribirLinea("     << ADVERTENCIA! >> Indexs Extras en Tabla '"+tabla.getNombre()+"' (2do ESQUEMA):\n");
                for(int i=0; i<indexsExtras.size(); i++){
                    idx = (Index) indexsExtras.elementAt(i);
                    arch.escribirLinea("        ");
                    idx.showIndex(arch);
                    arch.escribirLinea("\n");
                }
                arch.escribirLinea("\n");
            }
        }
        

        /*
         * INICIA COMPARACION DE CHECKs
         */
        if((!tabla.checks.isEmpty()||!(this.checks.isEmpty()))){
            arch.escribirLinea("\n  CHECKS:\n");
            Check ck;
            for(int j=0; j < tabla.checks.size(); j++){
                ck = (Check) tabla.checks.elementAt(j);
                posActual = this.existNombreCheck(ck.getNombre());
                if(0 <= posActual){
                    ck.compararCheck((Check)this.checks.remove(posActual), arch);
                }
                else{
                    int existCond = this.existCondicionCheck(ck.getCondicion());
                    if(0 <= existCond) ck.compararCheck((Check)this.checks.remove(existCond), arch);
                    else checksExtras.addElement(ck);
                }
            }
            if(!this.checks.isEmpty()){
                arch.escribirLinea("\n      << ADVERTENCIA! >> Checks Extras en Tabla '"+this.getNombre()+"' (1er ESQUEMA):\n");
                arch.escribirLinea("        ");
                this.showChecks(arch);
            }
            if(!checksExtras.isEmpty()){
                arch.escribirLinea("\n      << ADVERTENCIA! >> Checks Extras en Tabla '"+tabla.getNombre()+"' (2do ESQUEMA):\n");
                for(int i=0; i<checksExtras.size(); i++){
                    ck = (Check) checksExtras.elementAt(i);
                    arch.escribirLinea("        ");
                    ck.showCheck(arch);
                }
                arch.escribirLinea("\n");
            }
        }

        /*
         * INICIA COMPARACION DE TRIGGERs
         */
        if((!tabla.triggers.isEmpty()||!(this.triggers.isEmpty()))){
            arch.escribirLinea("\n  TRIGGERS:\n");
            Trigger trig1;
            for(int j=0; j<tabla.triggers.size(); j++){
                trig1 = (Trigger) tabla.triggers.elementAt(j);
                posActual = this.existTriggers(trig1.getNombre());
                if(0 <= posActual){
                    trig1.compararTrigger((Trigger)this.triggers.remove(posActual),this.nombre, arch);
                }
                else triggerExtras.addElement(trig1);
            }
            if(!this.triggers.isEmpty()){
                arch.escribirLinea("\n    << ADVERTENCIA! >> Triggers Extras en Tabla '"+this.getNombre()+"' (1er ESQUEMA):\n");
                this.showTriggers(arch);
            }
            if(!triggerExtras.isEmpty()){
                arch.escribirLinea("\n    << ADVERTENCIA! >> Triggers Extras en Tabla '"+tabla.getNombre()+"' (2do ESQUEMA):\n");
                for(int i=0; i<triggerExtras.size(); i++){
                    trig1 = (Trigger) triggerExtras.elementAt(i);
                    trig1.showTrigger(this.getNombre(), arch);
                }
                arch.escribirLinea("\n");
            }
        }

    }//compararTabla
    

}
